﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Input;
using System.Windows.Media;
using TheGameClient.Processes;
using TheGameClient.Webservices;
using Waaahsabi.Controls.FileSystem;

namespace TheGameClient
{
	public class ProgramFileCopier : ProgramBase
	{
		public override ulong InterfaceId
		{
			get { return new Guid("{825DF624-17A8-49ba-A9F2-3ED87F33C4D0}").ToLong(); }
		}

		public override string ProcessName
		{
			get { return "File Copying Tool"; }
		}

		protected override bool OnlyLocal
		{
			get { return false; }
		}

		protected override string SuccessStatus
		{
			get { return "File copying successful."; }
		}

		protected override string FailureStatus
		{
			get { return "File copying failed."; }
		}

		protected override string DropErrorStatus
		{
			get { return "Remote to remote not possible."; }
		}

		public override void Initialize()
		{
			Control.StatusText = "Drag onto file to be copied.";
			base.Initialize();
		}

		protected override void OnAnimationCompleted(object sender, EventArgs e)
		{
			if (State == ProgramState.SourceSelected)
				return;
			Execute();
			State = ProgramState.None;
		}

		protected override void OnDrop(object sender, MouseButtonEventArgs e)
		{
			if (State == ProgramState.Busy)
				return;

			if (TopmostWindow == null)
				return;

			GenericSystemInterface gsi;
			bool isLocal = false;
			switch (State)
			{
			case ProgramState.None:
				gsi =
					VisualTreeHelper.FindElementsInHostCoordinates(e.GetPosition(null), TopmostWindow).OfType<GenericSystemInterface>()
						.FirstOrDefault();
				if (gsi == null)
					//no generic system interface found, thus we are either in a local filemanager, or something is wrong
				{
					GatewayFileManager gfm =
						VisualTreeHelper.FindElementsInHostCoordinates(e.GetPosition(null), TopmostWindow).OfType<GatewayFileManager>().
							FirstOrDefault();
					if (gfm == null)
						return;
					isLocal = true;
				}
				if (!isLocal)
				{
					SourceConnectionId = gsi.ConnectionId;
				}
				else
					SourceConnectionId = Guid.Empty;

				var sourceFile =
					VisualTreeHelper.FindElementsInHostCoordinates(e.GetPosition(null), TopmostWindow).OfType<IFileItem>().
						FirstOrDefault();
				if (sourceFile != null)
				{
					SourceFileId = sourceFile.FileId;
					State = ProgramState.SourceSelected;
					Control.ShowProgressAnimation(10);
					Control.StatusText = "Now drag into target file area";
				}
				break;
			case ProgramState.SourceSelected:
				gsi =
					VisualTreeHelper.FindElementsInHostCoordinates(e.GetPosition(null), TopmostWindow).OfType<GenericSystemInterface>()
						.FirstOrDefault();
				if (gsi == null)
					//no generic system interface found, thus we are either in a local filemanager, or something is wrong
				{
					GatewayFileManager gfm =
						VisualTreeHelper.FindElementsInHostCoordinates(e.GetPosition(null), TopmostWindow).OfType<GatewayFileManager>().
							FirstOrDefault();
					if (gfm == null)
						return;
					isLocal = true;
				}
				if (!isLocal)
				{
					TargetConnectionId = gsi.ConnectionId;
				}
				else
					TargetConnectionId = Guid.Empty;

				//here we can already cancel out if both, source and target, are remote
				if (SourceConnectionId != Guid.Empty && TargetConnectionId != Guid.Empty)
				{
					Control.StatusText = DropErrorStatus;
					return;
				}
				IFileManager targetContainer =
					VisualTreeHelper.FindElementsInHostCoordinates(e.GetPosition(null), TopmostWindow).OfType<IFileManager>().
						FirstOrDefault();
				if (targetContainer != null)
				{
					Container = targetContainer;
					TargetDirectoryId = targetContainer.DirectoryId;
					Control.Cursor = Cursors.Wait;
					Control.ShowReverseProgressAnimation(Speed);
					Control.StatusText = "Copying file...";
					State = ProgramState.Busy;
				}
				break;
			}
		}

		protected override void OnServiceResult(object sender, ExecuteProgramCompletedEventArgs e)
		{
			App.Client.ExecuteProgramCompleted -= OnServiceResult;
			Control.InterruptAnimation();
			Control.Cursor = Cursors.Arrow;
			if (e.Error != null)
			{
				App.ServerError();
				return;
			}
			OperationResult = e.Result;
			if (OperationResult)
			{
				Control.StatusText = SuccessStatus;
				if (Container != null)
					Container.RefreshContent();
			}
			else
			{
				Control.StatusText = FailureStatus;
			}
		}

		public override void Execute()
		{
			TheGameServiceClient client = App.Client;
			client.ExecuteProgramCompleted += OnServiceResult;
			client.ExecuteProgramAsync(App.InternalSessionId, ProgramId,
			                           new List<object> {SourceConnectionId, TargetConnectionId, SourceFileId, TargetDirectoryId});
		}
	}

	public class ProgramFileCopierFactory : UiFactoryBase
	{
		public override InterfaceCategory UiCategory
		{
			get { return InterfaceCategory.Program; }
		}

		public override IProcess CreateProgram()
		{
			return new ProgramFileCopier();
		}
	}
}